package commands;

import java.util.List;

import core.Controller;
import core.GameManager;
import core.Invitation;
import core.MessageManager;
import core.UserManager;
import user.User;
import messages.GiveUpMessage;
import messages.InvitationTimedOutMessage;
import messages.Message;
import messages.UserLoggedOutMessage;
import event.InvitationTimedOutEventArgs;
import event.UserLoggedOutEventArgs;
import game.Match;
import game.Player;


/**
 * The Quit command.
 * 
 * This command will handle Quit messages.
 */
public class QuitCommand extends Command {

	
	public QuitCommand(Message message, User user) {
		super(message, user);
	}
	
	
	@Override
	public void execute() {
		UserManager userManager = controller.getUserManager();
		GameManager gameManager = controller.getGameManager();
		MessageManager messageManager = controller.getMessageManager();
		Player player = this.user.getPlayer();
		
		synchronized (userManager) {
			// We must terminate every game this player is in and timeout his invitations.
			synchronized (gameManager) {
				
				List<Match> matchs = gameManager.getActiveMatchsByPlayer(this.user.getPlayer());
				for (Match match : matchs) {
					// Quiting during a match = giving up
					Message giveUpMessage = new GiveUpMessage(match.getId());
					Command command = new GiveUpCommand(giveUpMessage, this.user);
					command.execute();
				}
				
				List<Invitation> invitations = gameManager.getInvitationsWithPlayer(this.user.getPlayer());
				for (Invitation invitation : invitations) {
					gameManager.removeInvitation(invitation.getId());
					
					Controller.getInstance().fireInvitationTimedOutEvent(
		    				new InvitationTimedOutEventArgs(invitation, new InvitationTimedOutMessage(invitation.getId())));
				}
			}
		
			// Now we must clear the queue of undelivered messages for this user.
			messageManager.clearUserQueue(this.user);
			
			// Set the user state as offline
			userManager.setOffline(player.getLogin());
			controller.fireUserLoggedOutEvent(new UserLoggedOutEventArgs(new UserLoggedOutMessage(player.getLogin())));
		}
	}
}
